package com.hyh.fireworks.common.utils;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.hyh.fireworks.common.constant.StringConstants;
import com.hyh.fireworks.exception.file.FileMimeTypeException;
import com.hyh.fireworks.exception.file.FileNameLengthLimitException;
import com.hyh.fireworks.exception.file.FileSizeLimitException;
import org.apache.velocity.shaded.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * 文件上传工具类
 *
 * @author Summerday
 */
public class FileUploadUtil {


    /**
     * 默认大小 50M
     */
    public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
    /**
     * 默认的文件名最大长度 100
     */
    public static final int DEFAULT_FILE_NAME_LENGTH = 100;

    /**
     * 默认的上传地址
     */

    public static String upload(String baseDir, MultipartFile file) throws IOException {
        return upload(baseDir, file, MimeTypeUtil.DEFAULT_ALLOWED_EXTENSION);
    }

    /**
     * @param baseDir          相对应用的基目录
     * @param file             上传的文件对象
     * @param allowedExtension 上传文件的类型
     * @return 返回上传成功的文件名
     */
    public static String upload(String baseDir, MultipartFile file, String[] allowedExtension) throws IOException {

        int length = file.getOriginalFilename().length();
        if (length > FileUploadUtil.DEFAULT_FILE_NAME_LENGTH) {
            throw new FileNameLengthLimitException(length, FileUploadUtil.DEFAULT_FILE_NAME_LENGTH);
        }
        // 检测文件是否符合要求
        assertAllowed(file, allowedExtension);
        // 2020/11/12/[uuid].jpg
        String fileName = generateFileName(file);
        File desc = getAbsoluteFile(baseDir, fileName);
        file.transferTo(desc);
        return fileName;
    }

    private static File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
        File file = new File(uploadDir + StringConstants.SLASH + fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        if (!file.exists()) {
            file.createNewFile();
        }

        return file;
    }


    /**
     * 生成日期格式文件名
     */
    private static String generateFileName(MultipartFile file) {
        String extension = getExtension(file);
        return DateUtil.format(DateUtil.date(), "yyyy/MM/dd")
                + StringConstants.SLASH + UUID.fastUUID() + StringConstants.DOT + extension;
    }

    /**
     * 文件大小校验
     *
     * @param file 文件
     */
    private static void assertAllowed(MultipartFile file, String[] allowedExtension) {
        long size = file.getSize();
        if (size > DEFAULT_MAX_SIZE) {
            throw new FileSizeLimitException(size, FileUploadUtil.DEFAULT_MAX_SIZE);
        }
        // mongo.jpg
        String fileName = file.getOriginalFilename();
        // 扩展名 jpg
        String extension = getExtension(file);
        //类型不允许
        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) {
            throw new FileMimeTypeException(fileName, extension, allowedExtension);
        }

    }

    /**
     * 判断是否为允许的类型
     *
     * @param extension        文件类型
     * @param allowedExtension 允许类型
     */
    private static boolean isAllowedExtension(String extension, String[] allowedExtension) {

        for (String s : allowedExtension) {
            if (s.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;

    }

    /**
     * 获取文件名的后缀扩展名 不包括.
     *
     * @param file 文件
     * @return 后缀名
     */
    private static String getExtension(MultipartFile file) {
        // 扩展名 mongo.jpg --> jpg
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if (StrUtil.isEmpty(extension)) {
            extension = MimeTypeUtil.getExtension(file.getContentType());
        }
        return extension;

    }


}
